import os
import random  # 导入生成随机数包
import time

from fastapi import APIRouter, HTTPException, Depends, FastAPI
from starlette import status
import jwt
from pydantic import BaseModel
import sys
from backend.app.app.crud_pub.authentication import Authentication
from backend.app.app.crud_sys.query import get_user_pwd
from backend.app.app.api.utils.encryption import rsa_decrypt, rsa_encrypt
from backend.app.app.models.user import User_inf_regist
from backend.app.app.crud_sys.add import add_user_regis
from backend.app.app.crud_sys.query import get_all_user, get_departname, get_legalperson
from backend.app.app import rsa_private_key
from backend.app.app.models.user import name_pwd, user_info_revise
from backend.app.app.api.api_v1.use_token import create_access_token, SECRET_KEY, ALGORITHM, turn_exp
from backend.app.app.crud_sys.tb_user import get_online_tb, updata_online_tb, revise_user, get_old_, get_all_online
from backend.app.app.crud_pro.tb_userpro_base import revise_re, get_remark

user_router = APIRouter(prefix="/user", tags=["普通用户"])
User_token_efficient_time = 60
Judge_toke_refresh = 1
Admin_token_efficient_time = 100


class token1(BaseModel):
    token_data: str


# 验证当前用户令牌  str = Depends(OAuth2PasswordBearer(tokenUrl="/api_v1/user/login"))
async def verify_token_user(token: token1):
    token = token.token_data
    credentials_exception = HTTPException(
        status_code=status.HTTP_401_UNAUTHORIZED,
        detail="Could not validate credentials",
        headers={"WWW-Authenticate": "Bearer"},
    )
    try:
        # 验证令牌用户名，有效性，有效期
        #   解码令牌，并判断可行性
        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
        username: str = payload.get("sub")
        # 判断身份是否为user 或者 admin
        a = payload.get("status")
        if a != "user" and a != "admin":
            raise credentials_exception
        # 判断令牌是否可用
        if payload.get("iat") != payload.get("iat"):
            raise credentials_exception
        if username is None:
            raise credentials_exception
        # 判断令牌是否过期
        start = payload.get("iat")
        now = turn_exp()
        end = payload.get("exp")
        # print((end-start)/60)
        if now > end:
            raise credentials_exception
    except:
        raise credentials_exception

    if (now - start) / 60 > Judge_toke_refresh:
        # 之前的令牌作废
        # 创立新的令牌并返回
        if a == "user":
            access_token = create_access_token(data={"sub": username}, expires_delta=User_token_efficient_time,
                                               avai=True, user_status="user")
            return {"access_token": access_token, "token_type": "bearer", "user": username, "new": True}
        if a == "admin":
            access_token = create_access_token(data={"sub": username}, expires_delta=Admin_token_efficient_time,
                                               avai=True, user_status="admin")
            return {"access_token": access_token, "token_type": "bearer", "user": username, "new": True}
    else:
        return {"user": username, "new": False}


class id(BaseModel):
    user_id: str


class online_info(BaseModel):
    user_id: str
    online: int


class u_p_id(BaseModel):
    user_id: str
    proj_id: str
    remark: str


class u_p_id_(BaseModel):
    user_id: str
    proj_id: str


class LogOutData(BaseModel):
    user_id: str


@user_router.post("/logout", name="注销登录")
async def log_out(input_data: LogOutData, ver=Depends(verify_token_user)):
    # payload = jwt.decode(ver['access_token'], SECRET_KEY, algorithms=[ALGORITHM])
    # print(payload)
    return {
        "result": updata_online_tb(input_data.user_id, 0)
    }


@user_router.post("/read_remark", name="读备注")
async def read_remark(infomation: u_p_id_, ver=Depends(verify_token_user)):
    re = get_remark(user_id=infomation.user_id, pro_id=infomation.proj_id)
    return {"result": re, "verify": ver}


@user_router.post("/modify_remark", name="修改备注")
async def modify_re(infomation: u_p_id, ver=Depends(verify_token_user)):
    a = revise_re(info=infomation)
    return {"result": a, "verify": ver}


@user_router.post("/get_online", name="获取本单位在线人数")
async def get_online(user: id):
    online = get_online_tb(user.user_id)
    num = len(online)
    return {"Number_online": num}


@user_router.post("/updata_online", name="更新在线信息")
async def updata_online(user: online_info):
    updata = updata_online_tb(user_id=user.user_id, status=user.online)
    return {"result_updata": updata}


@user_router.post("/get_old_info", name="修改信息前信息")
async def get_old_info(u_id: id, ver=Depends(verify_token_user)):
    all_info = get_old_(uid=u_id)
    return {"result": all_info, "verify": ver}


@user_router.post("/revise_info", name="修改个人信息")
async def revise_info(information: user_info_revise, ver=Depends(verify_token_user)):
    re = revise_user(user=information)
    return {"result": re, "verify": ver}


@user_router.post("/get_ver_code", name="获取验证码")
async def get_ver_code():
    code = 'abcdefghijkmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWXYZ23456789'
    ver_code = ""
    for i in range(4):
        new_code = random.choice(code)
        ver_code += new_code
    return {"ver_code": ver_code}


# 获取所有用户名,法人，部门
@user_router.post("/get_inf/", name="返回用户,法人，部门")
async def get_user():
    all_user = get_all_user()
    all_legel_p = get_legalperson()
    all_dpart = get_departname()
    return {"user": all_user, "legel_person": all_legel_p, "depart": all_dpart}


# 普通用户登录
@user_router.post("/login", name="用户登录")
#   OAuth2PasswordRequestForm = Depends()
async def judge_user_pwd(name_pwd: name_pwd):  # 传入密码密文
    try:
        app = FastAPI()
        authentication = Authentication()
        # path = os.path.join(os.getcwd(), "authorizeOut.txt")
        datas = authentication.read_auth_file()
        limit_person = datas['online_num']
        limit_person = int(limit_person)
        all_online = len(get_all_online())
        result = limit_person > all_online
        if not result:
            return {
                "result": False,
                "message": "在线人数超过限制"
            }
        # 读取用户名并处理
        all_user = get_all_user()
        a = []
        b = []
        for i in all_user:
            a.append(i[0])
            b.append(i[1])
        all_user = a
        all_qua = b

        # 将前后端密码解密并判断
        front_password = rsa_decrypt(name_pwd.password, rsa_private_key)
        print(front_password)
    except Exception as e:
        print(e, e.__traceback__.tb_lineno)
        return {"username": False, "judge_user_approved": False, "password": False}

    if name_pwd.username not in all_user:
        print("not user")
        return {"username": False, "judge_user_approved": False, "password": False}
    else:
        if all_qua[(all_user.index(name_pwd.username))] == 1:
            # 获取后端密码
            back_password = get_user_pwd(name_pwd.username)
            id = back_password[1]
            back_password = back_password[0]
            # 处理后端密码
            back_password = rsa_decrypt(back_password, rsa_private_key)
            if front_password == back_password:
                access_token = create_access_token(data={"sub": name_pwd.username},
                                                   expires_delta=User_token_efficient_time, avai=True,
                                                   user_status="user")
                updata_online_tb(id, 1)
                return {"username": True, "judge_user_approved": True, "password": True, "access_token": access_token,
                        "user_id": id}
            else:
                return {"username": True, "judge_user_approved": True, "password": False}
        else:
            return {"username": True, "judge_user_approved": False, "password": False}


# 普通用户注册
@user_router.post("/registe", name="用户注册，返回bool")
async def save_user(user_inf_re: User_inf_regist):
    # 获取注册时间
    import datetime
    now = datetime.datetime.now().strftime("%Y-%m-%d")

    # 初始化信息
    update_date = now
    register_date = now
    check_date = None
    user_id = str(time.time()).replace('.', '')[:10]
    datetime.datetime.now()
    user_pwd = rsa_encrypt(user_inf_re.User_PWD)
    remark = user_inf_re.Remark
    user_name = user_inf_re.User_Name
    user_role = user_inf_re.User_Role
    belong_depart = user_inf_re.Belong_Depart
    job_name = user_inf_re.Job_Name
    user_truname = user_inf_re.User_TruName
    user_mobilenumber = user_inf_re.User_MobileNumber
    user_email = user_inf_re.User_Email
    legalperson_id = '1000'
    isqualified = 0
    check_name = None
    try:
        add_user_regis(update_date, register_date, check_date, user_id, user_pwd, remark,
                       user_name, user_role, belong_depart,
                       job_name, user_truname, user_mobilenumber,
                       user_email, legalperson_id,
                       isqualified, check_name)
        print("写入成功")
        return {"registe": True}
    except:
        print("未能写入")
        return {"registe": False}
